﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Yunlib.Works.UHF;

namespace Yunlib.Works
{
    public partial class Form1 : Form
    {
        private string sIP = ConfigurationManager.AppSettings["IP"];
        private string sPort = ConfigurationManager.AppSettings["PORT"];
        private string COM = ConfigurationManager.AppSettings["COM"];
        private string Baud = ConfigurationManager.AppSettings["BAUD"];

        Socket socket;
        byte[] bytes = new byte[4096];
        Thread searchThread;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(sIP), int.Parse(sPort));

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            socket.Blocking = true;
            try
            {
                socket.Connect(ipep);
               // richTextBox1.AppendText("链接成功\r\n");
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }

            int ret = 0;
            ret = ReaderApi.basic_init(transfer.CONNECT_SERIAL);   //初始化为串口通信模式
            uart_open_t _open = new uart_open_t(COM, int.Parse(Baud));

            ret = transfer.transfer_open(ref _open);

            if (global.OPER_OK == ret)
            {
                //this.Dispose();
                //this.Close();
                //global.m_cbBaute = cbBaute.SelectedIndex;        // 获取当前设置的波特率
                //global.m_cbCOM = cbCOM.SelectedIndex;
                //MainInterface.UpdataConnStatuTextLog("打开串口成功！");//Open Com successful");
                MessageBox.Show("打开串口成功");
                //MainInterface.EnableFormSet();//
                //MainInterface.get_version();

                //Init_param();
            }
            else
            {
                // MainInterface.UpdataConnStatuTextLog("打开串口失败！");//Open Com fail");
                MessageBox.Show("打开串口失败");
            }
            
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            updata_tags_listview();
        }

        #region Socket
        protected void threadFunc(string sendMsg)
        {
            try
            {
                byte[] msg;
                string bytesRec;
                // msg = Encoding.UTF8.GetBytes(str);
                //str = "11NN20180622    11115020180622    111150AO|AA660000000031|AB51082300015143|AC|CN001|AY1AZEC5C  " + Environment.NewLine;

                byte[] buffer = Encoding.UTF8.GetBytes(sendMsg);



                socket.Send(buffer);
                socket.Receive((bytes));
                bytesRec = Encoding.UTF8.GetString(bytes);

                string ab = "";
                string aj = "";
                List<string> li = Exstring(bytesRec);
                for (int i = 0; i < li.Count; i++)
                {
                    if (li[i].Length > 2)
                    {
                        if (li[i].Substring(0, 2) == "AB")
                        {
                            ab = li[i].Substring(2);
                        }
                        else if (li[i].Substring(0, 2) == "AJ")
                        {
                            aj = li[i].Substring(2);
                        }
                        
                    }
                }

                for (int index = 0; index < TagsList.Count; index++)
                {
                    if ((TagsList[index].BarCode == ab))
                    {
                        TagsList[index].Title = aj;
                    }
                }


                string ret;
                SetLog("获取的数据是" + bytesRec + "\r\n");
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }

        }



        /// <summary> 把命令解析成一个个单个信息存贮在list<>里 </summary> <param name="st"></param> <returns></returns>
        public List<string> Exstring(string st)
        {
            var li = new List<string>();

            string[] arr = st.Split('|');
            for (int i = 0; i < arr.Length; i++)
            {
                li.Add(arr[i]);
            }

            return li;
        }


        delegate void SetLogCallBack(string log);
        /// <summary>
        /// 更新richtextbox控件的具体方法
        /// </summary>
        /// <param name="str">传入的字符串</param>
        private void SetLog(string str)
        {
            //if (this.richTextBox1.InvokeRequired)
            //{
            //    SetLogCallBack d = new SetLogCallBack(SetLog);
            //    this.Invoke(d, new object[] { str });
            //}
            //else
            //    this.richTextBox1.AppendText(str);

        }
        #endregion

        #region UHF 读超高频

        private Thread multi_get_thread;
        private volatile bool _shouldStop;
        private volatile List<DataTag> TagsList = new List<DataTag>(2000);
        private void MultiReadTagData()
        {
            int ret = global.OPER_OK;
            string oper_result;

            if (multi_get_thread != null)
            {
                multi_get_thread.Abort();
            }
            multi_get_thread = new Thread(new ThreadStart(this._multi_get));
       
            ret = ReaderApi.StartInventoryMultiple(0x00);

            if (ret == global.OPER_OK)
            {
                global.MultiReadStatus = true;
                multi_get_thread.Start();
                //  _multi_get();
                oper_result = "启动循环查询标签成功！";
            }
            else
            {
                oper_result = "启动循环查寻标签失败！";//Start Multi query fail.
               
            }
            //ReaderStatus.Text = oper_result;
        }

        private void _multi_get()
        {
            //while (true)
            //{
            DateTime start = DateTime.Now;
            for (int i = 0; i < numericUpDown1.Value; i++)
            {
                multi_query_epc_t multi_epc = new multi_query_epc_t();
                //if (!multi_get_thread.IsAlive)
                //{
                //    break;
                //}

                int ret = ReaderApi.InventoryMultipleData(ref multi_epc);


                multi_analyze_data(multi_epc);
                Thread.Sleep(300);
            }
            DateTime end = DateTime.Now;
            TimeSpan ts = end - start;

            this.Invoke(new Action(() =>
            {
                lblTime.Text = ts.TotalSeconds + "秒";
            }));
            //}
        }

        private void multi_analyze_data(multi_query_epc_t tags)
        {
            if ((tags.in_count_msb != 0) || (tags.in_count_lsb != 0) || (tags.out_count_msb != 0) || (tags.out_count_lsb != 0))
            {
                global.InStatistics = pc_calculate(tags.in_count_msb, tags.in_count_lsb);
                global.OutStatistics = pc_calculate(tags.out_count_msb, tags.out_count_lsb);
            }

            for (int index = 0; index < tags.packet_num; index++)
            {
              ////  Thread.Sleep(700);
              //  if ((tags.tags_epc[index].epc.epc_len > 124) || (tags.tags_epc[index].epc.epc_len <= 0))
              //  {
              //      continue;
              //  }

                //SetAccumulateCount();

                string temp_epc = epc_format(tags.tags_epc[index].epc.epc, tags.tags_epc[index].epc.epc_len);
                byte ant = tags.tags_epc[index].ant_id;


                // 判断当前标签是会否存在列表中
                int offset = 0;
                if (-1 == (offset = tags_list_traverse(temp_epc, ant)))
                {
                    
                    DataTag tmp_tag = new DataTag();
                    tmp_tag.Count = 1;
                    tmp_tag.AntId = tags.tags_epc[index].ant_id;
                    tmp_tag.Pc = pc_calculate(tags.tags_epc[index].epc.pc_msb, tags.tags_epc[index].epc.pc_lsb);
                    tmp_tag.Rssi = rssi_calculate(tags.tags_epc[index].rssi_msb, tags.tags_epc[index].rssi_lsb);
                    tmp_tag.Epc = temp_epc;
                    tmp_tag.Tid = tid_format(tags.tags_epc[index].tid, tags.tags_epc[index].tid_len);
                    tmp_tag.FirstTime = "";
                    tmp_tag.LatestTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);
                    tmp_tag.BarCode = temp_epc.Replace("-", "").Substring(7, 9);
                    TagsList.Add(tmp_tag);
                    
                    //string str = "1720181206    155911AO|AB" + temp_epc.Replace("-","").Substring(10, 6) + "|AC|AY4AZF618";
                    //Thread thread = new Thread(new ThreadStart(delegate () { threadFunc(str); }));
                    //thread.Start();
                }
                else        // 标签已存在，增加count 即可
                {
                    // 写保护
                    {
                        TagsList[offset].Count += 1;
                        //TagsList[offset].Pc = pc_calculate(tags.tags_epc[index].epc.pc_msb, tags.tags_epc[index].epc.pc_lsb);
                        //TagsList[offset].Rssi = rssi_calculate(tags.tags_epc[index].rssi_msb, tags.tags_epc[index].rssi_lsb);
                        //TagsList[offset].AntId = tags.tags_epc[index].ant_id;
                        //TagsList[offset].FirstTime = "";
                        TagsList[offset].LatestTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);
                    }
                }
               

            }
        }

        private ushort pc_calculate(byte pc_msb, byte pc_lsb)
        {
            ushort temp_pc = (ushort)((((ushort)pc_msb) << 8) + (ushort)pc_lsb);

            return temp_pc;
        }

        private int tags_list_traverse(string epc, byte ant)
        {
            for (int index = 0; index < TagsList.Count; index++)
            {
                
                if ((TagsList[index].Epc == epc))
                {
                    return index;
                }
            }

            return -1;
        }

        public void search()
        {
            while (true)
            {
                if (DataGridViewList.RowCount > 0)
                {
                    for (int index = 0; index < TagsList.Count; index++)
                    {
                        if (!string.IsNullOrWhiteSpace(TagsList[index].BarCode) && string.IsNullOrWhiteSpace(TagsList[index].Title))
                        {
                            string str = "1720181206    155911AO|AB" + TagsList[index].BarCode + "|AC|AY4AZF618";
                            //Thread thread = new Thread(new ThreadStart(delegate () { threadFunc(str); }));
                            //thread.Start();

                            threadFunc(str);
                        }

                    }
                }
            }
        }

        private string epc_format(byte[] epc, byte epc_len)
        {
            string str_epc = "";
            for (int index = 0; index < epc_len; index++)
            {
                str_epc += epc[index].ToString("X2");
                if (index < epc_len - 1)
                {
                    str_epc += "-";
                }
            }
            return str_epc;
        }

        private string tid_format(byte[] tid, int tid_len)
        {
            string str_epc = "";
            for (int index = 0; index < tid_len; index++)
            {
                str_epc += tid[index].ToString("X2");
                if (index < tid_len - 1)
                {
                    str_epc += "-";
                }
            }
            return str_epc;
        }

        private double rssi_calculate(byte rssi_msb, byte rssi_lsb)
        {
            ushort temp_rssi = (ushort)(((ushort)rssi_msb << 8) + (ushort)rssi_lsb);
            double sh_rssi = (double)(short)temp_rssi / 10;

            return sh_rssi;
        }

        private void updata_tags_listview()
        {
            List<DataTag> tmp_tags_list = new List<DataTag>(1000);

            //lock (tags_list)
            {
                tmp_tags_list = TagsList;
            }

            for (int index = 0; index < tmp_tags_list.Count; index++)
            {
                UpdataLabel(tmp_tags_list[index], index);
            }
        }

        private void UpdataLabel(DataTag tag_item, int nIndex)
        {
            //转换成string
            string str_pc = "";
            string str_rssi = "";

            string str_ant_id = tag_item.AntId.ToString();
            string str_epc = tag_item.Epc;
            string str_tid = tag_item.Tid;
            if (tag_item.Pc != 0)
            {
                str_pc = tag_item.Pc.ToString("X2");
            }

            string str_read_cnt = tag_item.Count.ToString();
            if ((tag_item.Rssi - 0.0) > 0.000001 || (tag_item.Rssi - 0.0) < 0.000001)
            {
                str_rssi = tag_item.Rssi.ToString("f1");
            }

            string str_timet0 = tag_item.FirstTime;
            string str_time = tag_item.LatestTime;


            string[] arr = new string[11];
            arr[0] = (DataGridViewList.RowCount + 1).ToString();
            arr[1] = str_ant_id;
            arr[2] = str_epc;
            arr[3] = str_tid;
            arr[4] = str_pc;
            arr[5] = str_rssi;
            arr[6] = str_read_cnt;
            arr[7] = str_timet0;
            arr[8] = str_time;
            arr[9] = tag_item.BarCode;
            arr[10] = tag_item.Title;


            bool Exist = false;
            //判断标签是否被重复扫描
            //for (int iCount = 0; iCount < DataGridViewList.RowCount;iCount++ )
            foreach (DataGridViewRow dt in this.DataGridViewList.Rows)
            {
                if (dt.Cells[2].Value.ToString() == str_epc)
                {
                    dt.Cells[1].Value = str_ant_id;
                    dt.Cells[3].Value = str_tid;
                    dt.Cells[4].Value = str_pc;
                    dt.Cells[5].Value = str_rssi;
                    dt.Cells[6].Value = str_read_cnt;
                    dt.Cells[7].Value = str_timet0;
                    dt.Cells[8].Value = str_time;
                    dt.Cells[9].Value = tag_item.BarCode;
                    dt.Cells[10].Value = tag_item.Title;
                    Exist = true;
                    break;
                }
            }

            if (!Exist)
            {
                DataGridViewList.Rows.Insert(DataGridViewList.RowCount, arr);
            }
        }


        #endregion

        private void DataGridViewList_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (searchThread != null)
            {
                searchThread.Abort();
            }
            searchThread = new Thread(new ThreadStart(search));
         //   searchThread.IsBackground = true;
            searchThread.Start();
            MultiReadTagData();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            
            multi_get_thread.Abort();
            searchThread.Abort();
            TagsList.Clear();
            while (this.DataGridViewList.Rows.Count != 0)
            {
                this.DataGridViewList.Rows.RemoveAt(0);
            }
            
            lblTime.Text = "";
        }
    }
}
